﻿using Sirenix.OdinInspector;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using App.Common;
using QxFramework.Core;
using System;
public class SpawnManager : LogicModuleBase, ISpawnManager
{
    public SpawnObjDatas _spawnObjDatas;
    public SpawnObjDatas GetSpawnObjDatas()
    {
        return _spawnObjDatas;
    }
    public override void Init()
    {
        base.Init();
        if (!RegisterData(out _spawnObjDatas))
        {
            InitAllSpawnData();
        }
    }
    public void InitAllSpawnData()
    {
        _spawnObjDatas._spawnData = new Dictionary<string, SpawnObjData>();
        ClearAll();
    }

    public override void FixedUpdate()
    {
        base.FixedUpdate();
        UpdateAllSpawner();
    }

    /// <summary>
    /// 同步场上所有Mono
    /// </summary>
    public void UpdateAllSpawner()
    {
        foreach (string key in _spawnObjDatas._ObjList.Keys)
        {
            if (!_spawnObjDatas._spawnData.ContainsKey(key))
            {
                RemoveObj(key);
                break;
            }
        }
        foreach (string key in _spawnObjDatas._spawnData.Keys)
        {
            if (_spawnObjDatas._ObjList.ContainsKey(key))
            {
                if (_spawnObjDatas._ObjList[key] == null)
                {
                    _spawnObjDatas._ObjList.Remove(key);
                    break;
                }
            }
            else
            {
                AddObj(key, out GameObject Clone);
                Clone.GetComponent<MonoSpawner>().NotStartOnScene = true;
            }
            _spawnObjDatas._ObjList[key].transform.position = _spawnObjDatas._spawnData[key].Pos;
            SpawnObjs(_spawnObjDatas._spawnData[key]);
            if (IsSpawnerCreatedAll(_spawnObjDatas._spawnData[key]))
            {
                RemoveSpawner(key);
                break;
            }
        }
    }
    /// <summary>
    /// 添加新的Spawner
    /// </summary>
    public void AddSpawner(string Name, SpawnObjData spawnObjData)
    {
        string NameTemp = Name + "_0";
        int IDtemp = 0;
        while (_spawnObjDatas._spawnData.ContainsKey(NameTemp))
        {
            IDtemp++;
            NameTemp = Name + "_" + IDtemp;
        }
        _spawnObjDatas._spawnData.Add(NameTemp, spawnObjData);
    }
    public void AddObj(string Name, out GameObject Clone)
    {
        GameObject clone;
        if (GameObject.Find(Name) != null)
        {
            Clone = GameObject.Find(Name);
            _spawnObjDatas._ObjList.Add(Name, Clone);
            Debug.Log(Name);
            return;
        }
        clone = ResourceManager.Instance.Instantiate("Prefabs/CreatedSpawners/" + Name.Split('_')[0], GameObject.Find("SceneObjs").transform);
        clone.name = Name;
        clone.transform.position = _spawnObjDatas._spawnData[Name].Pos;
        Clone = clone;
        _spawnObjDatas._ObjList.Add(Name, clone);
    }
    /// <summary>
    /// 移除已有的Spawner
    /// </summary>
    public void RemoveSpawner(string Name)
    {
        if (!_spawnObjDatas._spawnData.ContainsKey(Name))
        {
            Debug.LogError("SpawnerMonoList没有" + Name);
            return;
        }
        _spawnObjDatas._spawnData.Remove(Name);
    }
    private void RemoveObj(string Name)
    {
        GameObject clone = _spawnObjDatas._ObjList[Name];
        _spawnObjDatas._ObjList.Remove(Name);
        ResourceManager.Instance.Destroy(clone);
    }

    /// <summary>
    /// 清除所有Spawn
    /// </summary>
    public void ClearAll()
    {
        _spawnObjDatas._spawnData.Clear();
    }

    bool PreSpawn=false;
    /// <summary>
    /// spawn主逻辑
    /// </summary>
    public void SpawnObjs(SpawnObjData spawnObjData)
    {
        for (int i=0;i< spawnObjData._spawnData.Count; i++)
        {
            if (spawnObjData.NotActivated)
            {
                continue;
            }
            if (spawnObjData._SpawnDataRecord[i].SpawnedTimes < spawnObjData._spawnData[i].SpawnCount)
            {
                if (spawnObjData._SpawnDataRecord[i].LastSpawnTime < 0)
                {
                    PreSpawn = false;
                    spawnObjData._SpawnDataRecord[i].LastSpawnTime = spawnObjData._spawnData[i].SpawnTimes;
                    SpawnFunc(spawnObjData._spawnData[i], spawnObjData._SpawnDataRecord[i], spawnObjData.Pos);
                }
                else
                {
                    spawnObjData._SpawnDataRecord[i].LastSpawnTime -= Time.deltaTime;
                }
            }
        }
    }
    public void SpawnFunc(SpawnData spawnData, SpawnDataRecord spawnDataRecord, Vector3 Pos)
    {
        if (spawnData.Name.Contains("Player"))//player就从playerdata获取数据
        {
            for(int i=0;i< GameMgr.Get<IPlayerDataManager>().GetPlayerDatas().PlayerDatas.Count; i++)
            {
                spawnDataRecord.SpawnedTimes += 1;
                Mono m = new Mono();
                m = GameMgr.Get<IPlayerDataManager>().GetPlayerDatas().PlayerDatas[i].PlayerMono;
                m.Position = Pos;
                GameMgr.Get<IMonoManager>().AddMono(GameMgr.Get<IPlayerDataManager>().GetPlayerDatas().PlayerDatas[i].PlayerName, m);
            }
        }
        else//敌人就初始化
        {
            CoroutineManager.Instance.StartCoroutine(SpawnMono(0.25f, spawnData, spawnDataRecord, Pos));
        }
    }
    IEnumerator SpawnMono(float sec, SpawnData spawnData, SpawnDataRecord spawnDataRecord, Vector3 Pos)
    {
        PreSpawnFun(Pos);
        yield return new WaitForSeconds(sec);
        spawnDataRecord.SpawnedTimes += 1;
        Mono m = new Mono();
        m = GetInitMonoData(spawnData.Name);
        m.Position = Pos;
        GameMgr.Get<IMonoManager>().AddMono(spawnData.Name, m);
    }

    public void PreSpawnFun(Vector3 Pos)
    {
        GameObject clone = ResourceManager.Instance.Instantiate("Prefabs/Others/PreIns");
        clone.transform.position = Pos;
    }

    private bool IsSpawnerCreatedAll(SpawnObjData spawnObjData)
    {
        bool IsCreatedAll = true;
        for (int i = 0; i < spawnObjData._spawnData.Count; i++)
        {
            if (spawnObjData._SpawnDataRecord[i].SpawnedTimes < spawnObjData._spawnData[i].SpawnCount)
            {
                IsCreatedAll = false;
            }
        }
        return IsCreatedAll;
    }

    /// <summary>
    /// spawn初始化mono数据
    /// </summary>
    public Mono GetInitMonoData(string Name)
    {
        Mono m = new Mono();
        m.HPData.HPCeiling = Data.Instance.TableAgent.GetInt("AllMono", Name, "HP");
        m.HPData.HPValue = m.HPData.HPCeiling;
        m.HPData.RecoverSpeed = 0;
        m.AttackTipsData.ValueCeiling = Data.Instance.TableAgent.GetFloat("AllMono", Name, "AttackTipsTime");
        m.AttackTipsData.CurrentValue = 0;
        m.MPData.MPCeiling = Data.Instance.TableAgent.GetInt("AllMono", Name, "MP");
        m.MPData.RecoverSpeed = Data.Instance.TableAgent.GetInt("AllMono", Name, "MPRecover");
        m.LPData.LPCeiling = Data.Instance.TableAgent.GetInt("AllMono", Name, "LP");
        m.LPData.RecoverSpeed = Data.Instance.TableAgent.GetInt("AllMono", Name, "LPRecover");
        m.LPData.LPValue = m.LPData.LPCeiling;
        m.Speed = Data.Instance.TableAgent.GetFloat("AllMono", Name, "Speed");
        m.Range = Data.Instance.TableAgent.GetFloat("AllMono", Name, "Range");
        m.Attr = (MonoAttribute)Data.Instance.TableAgent.GetInt("AllMono", Name, "Attr");
        string AllSkill = Data.Instance.TableAgent.GetString("AllMono", Name, "Skill");
        if (AllSkill.Contains("|"))
        {
            string[] AllSkills = AllSkill.Split('|');
            for(int i=0; i< AllSkills.Length; i++)
            {
                m.SkillList.Add(GameMgr.Get<ISkillManager>().InitSkillData(int.Parse(AllSkills[i])));
            }
        }
        else
        {
            m.SkillList.Add(GameMgr.Get<ISkillManager>().InitSkillData(int.Parse(AllSkill)));
        }
        if (Name.Contains("Player"))
        {
            RandomPlayerSkill(m);
        }
        m.monoRealtimeStatus = new MonoRealtimeStatus();
        return m;
    }
    //随机初始化玩家技能
    private void RandomPlayerSkill(Mono m)
    {
        List<string> AllSkillID = Data.Instance.TableAgent.CollectKey1("AllSkill");
        List<int> AllSkillIDTemp = new List<int>();
        foreach (string ID in AllSkillID)
        {
            if (int.Parse(ID) == 0)
            {
                continue;
            }
            if (int.Parse(ID) > 23)
            {
                continue;
            }
            AllSkillIDTemp.Add(int.Parse(ID));
        }
        AllSkillIDTemp = ListRandom(AllSkillIDTemp);
        m.SkillList.Add(GameMgr.Get<ISkillManager>().InitSkillData(AllSkillIDTemp[0]));
        m.SkillList.Add(GameMgr.Get<ISkillManager>().InitSkillData(AllSkillIDTemp[1]));
        m.SkillList.Add(GameMgr.Get<ISkillManager>().InitSkillData(AllSkillIDTemp[2]));
    }

    private List<int> ListRandom(List<int> myList)
    {

        System.Random ran = new System.Random();
        int index = 0;
        int temp = 0;
        for (int i = 0; i < myList.Count; i++)
        {

            index = ran.Next(0, myList.Count - 1);
            if (index != i)
            {
                temp = myList[i];
                myList[i] = myList[index];
                myList[index] = temp;
            }
        }
        return myList;
    }
}
public class SpawnObjDatas : GameDataBase
{
    public Dictionary<string, SpawnObjData> _spawnData = new Dictionary<string, SpawnObjData>();
    public Dictionary<string, GameObject> _ObjList = new Dictionary<string, GameObject>();
}
public class SpawnObjData
{
    public string PrefabName;
    public bool NotActivated;
    public List<SpawnData> _spawnData = new List<SpawnData>();
    public List<SpawnDataRecord> _SpawnDataRecord = new List<SpawnDataRecord>();
    public Vector3 Pos = Vector3.zero;
}
[Serializable]
public class SpawnData
{
    public string Name;
    public int SpawnCount;
    public int SpawnTimes;
}
public class SpawnDataRecord
{
    public int SpawnedTimes = 0;
    public float LastSpawnTime = 0;
}
